﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using AutoMapper;
using Newtonsoft.Json;
using TheNorthStar.Api.Requests;
using TheNorthStar.Api.Results;
using TheNorthStar.Web.Application;

using TheNorthStar.Web.Application.Services;
using Booking = TheNorthStar.Domain.Booking;

namespace TheNorthStar.Web.Controllers
{

    public class BookingsController : Controller
    {
        private readonly IBookingService _bookingService;
        private readonly Dictionary<string, double> _tempLatLng;
        public BookingsController(IBookingService bookingService)
        {
            _bookingService = bookingService;

            _tempLatLng = new Dictionary<string, double>();

            _tempLatLng.Add("0", -35.278344);
            _tempLatLng.Add("-35.26054", -35.278340);
            _tempLatLng.Add("149.13247", 149.129080);
            
            _tempLatLng.Add("-35.278340", -35.279050);
            _tempLatLng.Add("149.129080", 149.128940);

            _tempLatLng.Add("-35.279050", -35.279425);
            _tempLatLng.Add("149.128940", 149.128346);

            _tempLatLng.Add("-35.279425", -35.280025);
            _tempLatLng.Add("149.128346", 149.126666);

            _tempLatLng.Add("-35.280025", -35.281400);
            _tempLatLng.Add("149.126666", 149.125556);

            _tempLatLng.Add("-35.281400", -35.283510);
            _tempLatLng.Add("149.125556", 149.126125);

            _tempLatLng.Add("-35.283510", -35.278340);
            _tempLatLng.Add("149.126125", 149.129080);
        }

        public JsonResult NewBookings(int driverId, double lat, double lng)
        {

            return Json(1);
        }
        //
        // GET: /Bookings/
        [HttpGet]
        public JsonResult Index(int? id)
        {
            if(id.HasValue)
            {
                Booking domainBooking = _bookingService.Get(id.Value);
                Api.Results.Booking dtoBooking = Mapper.Map<Booking, Api.Results.Booking>(domainBooking);

                string jsonResult = Newtonsoft.Json.JsonConvert.SerializeObject(dtoBooking);
                return Json(dtoBooking, JsonRequestBehavior.AllowGet);
            }

            //403 = forbidden, at this stage only admins can get the list of overall bookings
            Response.StatusCode = 403;
            return Json(new { success = false }, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public JsonResult Index(NewBooking item)
        {
            Booking booking = _bookingService.Create(item);
            var res = Mapper.Map<Domain.Booking, Api.Results.Booking>(booking);
            var jsonData = Newtonsoft.Json.JsonConvert.SerializeObject(res);

            
            return Json(res);
        }

        [HttpPut]
        public JsonResult Index(CancelBookingRequest cancelBooking, bool? driverRating)
        {
            GeneralResult result = new GeneralResult{ Success = false, Message = "unknown error" };
            Booking booking = _bookingService.Get(cancelBooking.BookingId);

            

            //the logic on what to do should probably go to into a helper method.
            //Controller methods should be lean and mean.
            //Discussion: Should the "confirm" booking logic should also belong here. Or should it be an update
            // on the driver part of teh api?
            if (booking != null && booking.Customer.PhoneNumber == cancelBooking.PhoneNumber && booking.Customer.IMEI == cancelBooking.IMEI)
            {
                if (cancelBooking.isCancelled)
                {
                    booking.Status = "CANCELLED";
                }
                else if (driverRating.HasValue)
                {
                    booking.DriverRating = driverRating;
                }
                _bookingService.Update(booking);

                result.Success = true;
                result.Message ="Update successful";
            }
            else
            {
                result.Success = false;
                result.Message = "booking not found";
                
            }

            return Json(result);
        }

        //temp action to setup some test data scenarios
        public EmptyResult ConfirmBooking(int id)
        {
            Booking booking = _bookingService.Get(id);
            booking.Status = "CONFIRMED";
            booking.DriverId = 1;

            _bookingService.Update(booking);
            return new EmptyResult();
        }

        //temp action to setup some test data scenarios
        public EmptyResult updateDriverLocation(int id)
        {
            Booking booking = _bookingService.Get(id);
            booking.Driver.LastKnownLatitude = GetNextLatLng(booking.Driver.LastKnownLatitude.ToString());
            booking.Driver.LastKnownLongitude = GetNextLatLng(booking.Driver.LastKnownLongitude.ToString());

            _bookingService.Update(booking);
            return new EmptyResult();
        }

        private decimal GetNextLatLng(string key)
        {
            return (decimal)_tempLatLng[key];
            
        }

    }
}
